package org.glickr.api.photos

import groovy.util.slurpersupport.GPathResult
import org.glickr.api.FlickrApiMethod
import org.glickr.FlickrPhoto
import org.glickr.FlickrPhotoExif
import org.glickr.FlickrServicePluginException
import org.glickr.FlickrServiceApiException

/* ----------------------------------------------------------------------------------------------------
REQUEST: flickr.photos.getExif
INFO: Retrieves a list of EXIF/TIFF/GPS tags for a given photo. The calling user must have permission to view the photo.

AUTHENTICATION: This method does not require authentication.

ARGUMENTS:
api_key (Required): Your API application key.
photo_id (Required): The id of the photo to fetch information for.
secret (Optional): The secret for the photo. If the correct secret is passed then permissions checking is skipped. This enables the 'sharing' of individual photos by passing around the id and secret.

EXAMPLE RESPONSE:
<photo id="4424" secret="06b8e43bc7" server="2">
  <exif tagspace="TIFF" tagspaceid="1" tag="271" label="Manufacturer">
    <raw>Canon</raw>
  </exif>
  <exif tagspace="EXIF" tagspaceid="0" tag="33437" label="Aperture">
    <raw>90/10</raw>
    <clean>f/9</clean>
  </exif>
  <exif tagspace="GPS" tagspaceid="3" tag="4" label="Longitude">
    <raw>64/1, 42/1, 4414/100</raw>
    <clean>64&deg; 42' 44.14&amp;quot;</clean>
  </exif>
</photo>
The <clean> element contains a pretty-formatted version of the tag where availabale.
---------------------------------------------------------------------------------------------------- */

class photosGetExif implements FlickrApiMethod {
    //
    //  API METHOD
    //
    static final String apiMethod = 'flickr.photos.getExif'

    //
    //  VALIDATOR
    //
    Closure validatorClosure = { FlickrPhoto photo ->
        if (!photo || !photo?.id) { return [validated:false, message:"Required value 'FlickrPhoto.id' is missing"] }
        return [validated:true]
    }

    //
    //  PARAMS
    //
    Closure paramsClosure = { FlickrPhoto photo ->
        [photo_id:photo?.id, secret:(photo?.secret ?:'')]
    }

    //
    //  PROCESSOR
    //
    Closure processorClosure = { GPathResult response, FlickrPhoto photo ->
        photo.camera = response.photo.@camera.toString()
        photo.secret = response.photo.@secret.toString()
        photo.serverId = response.photo.@server.toInteger()
        photo.farmId = response.photo.@farm.toInteger()

        photo.exif = []
        response.photo.children().findAll{ it.name() == 'exif' }.each {
            photo.exif.add(
                new FlickrPhotoExif(
                        tagSpace: it.@tagspace.toString(),
                        tagSpaceId: it.@tagspaceid.toInteger(),
                        tag: it.@tag.toString(),
                        label: it.@label.toString(),
                        raw: it.raw.toString()
                )
            )
        }
        return photo
    }

    //
    //  ERROR CODES
    //
    Closure errorsClosure = { GPathResult response ->
        if (response.err.@code.toInteger() == 1) { return null }      // photo not found
        if (response.err.@code.toInteger() == 2) { return null }      // permission denied

        // recoverable errors
        if ([100,105,116].contains(response.err.@code.toInteger())) {
            return new FlickrServiceApiException(response)
        } else {
            return new FlickrServicePluginException(response)
        }
    }
}
